package com.achievo.know.domain.infra.hibernate;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.FetchMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.stereotype.Repository;

import com.achievo.know.domain.Role;
import com.achievo.know.domain.User;
import com.achievo.know.domain.UserRepository;
import com.achievo.know.pojo.RoleInit;
import com.dayatang.spring.repository.BaseEntityRepositoryHibernateSpring;
/**
 * 
 * @author lingen.liu
 * Account 仓储的实现
 */
@Repository
public class UserRepositoryImpl extends
		BaseEntityRepositoryHibernateSpring<User, Long> implements UserRepository {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public UserRepositoryImpl(){
		super(User.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> queryAccountByRole(Role role) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.createAlias("roles", "rs");
		criteria.add(Restrictions.eq("rs.id", role.getId()));
		criteria.setFetchMode("roles", FetchMode.JOIN);
		List<User> acountList = getHibernateTemplate().findByCriteria(criteria);
		return acountList;
	
	}

	@Override
	public boolean isEmailExist(String email) {
		Object account = getSingleResult("from User a where a.email = ?", new Object[]{email});
	    if(account!=null)return true;
	    return false;
	}

	@Override
	public boolean isUsernameExist(String username) {
		Object account = getSingleResult("from User a where a.username = ?", new Object[]{username});
	    if(account!=null)return true;
	    return false;
	}

	/**
	 * 根据用户的姓名获取用户信息,并且连同角色信息一同获取
	 */
	public User get(String username) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("username", username));
		List<User> acountList = getHibernateTemplate().findByCriteria(criteria);
		if(acountList.size()==0)return null;
		return acountList.get(0);
	}

	@Override
	public User getWithRole(String username) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("username", username));
		criteria.setFetchMode("roles", FetchMode.JOIN);
		List<User> acountList = getHibernateTemplate().findByCriteria(criteria);
		if(acountList.size()==0)return null;
		return acountList.get(0);
	}

	@Override
	public User get(String userName, boolean isLocal) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("username", userName));
		criteria.add(Restrictions.eq("isLocal", isLocal));
		List<User> acountList = getHibernateTemplate().findByCriteria(criteria);
		if(acountList.size()==0)return null;
		return acountList.get(0);
	}

	@Override
	public void createUser(User user) {
		user.setLocal(false);
		user.setRegistryDate(new Date());
		user.setLocked(false);
		save(user);
	}

	@Override
	public void bulkSave(final List<User> users,final Role commonEmp) {
		//Set<Role> roles = new HashSet<Role>();
		//roles.add(commonEmp);
		for(User user:users){
			//user.setRoles(roles);
			System.out.println("save "+user.getUsername());
			save(user);
			addRole(user.getId(),RoleInit.EMP);
		}
		/*
		String sql="insert into RAMS_USER(USERNAME,REAL_NAME,REGISTRY_DATE,IS_LOCKED,IS_LOCAL,VERSION,EMAIL,DEPT) values(?,?,?,?,?,?,?,?)";
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter(){

			@Override
			public int getBatchSize() {
				return users.size();
			}

			@Override
			public void setValues(PreparedStatement ps, int i)
					throws SQLException {
				System.out.println(i);
				ps.setString(1, users.get(i).getUsername());
				ps.setString(2, users.get(i).getRealName());
				ps.setDate(3, new java.sql.Date(users.get(i).getRegistryDate().getTime()));
				ps.setBoolean(4, users.get(i).getLocked());
				ps.setBoolean(5, users.get(i).isLocal());
				ps.setInt(6, 0);
				ps.setString(7, users.get(i).getEmail());
				ps.setString(8, users.get(i).getDeptment());
			}
		});
		
		String roleSql="insert into rams_user_r_role(USER_ID,ROLE_ID) values(?,?)";
		jdbcTemplate.batchUpdate(roleSql, new BatchPreparedStatementSetter(){

			@Override
			public int getBatchSize() {
				return users.size();
			}

			@Override
			public void setValues(PreparedStatement ps, int i)
					throws SQLException {
				System.out.println(i);
				ps.setLong(1, users.get(i).getId());
				ps.setLong(2, commonEmp.getId());
			}
		});*/
	}

	@Override
	public void bulkDisable(final List<User> users) {
		String sql="update RAMS_USER set IS_LOCKED=? where ID=?";
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter(){

			@Override
			public int getBatchSize() {
				return users.size();
			}

			@Override
			public void setValues(PreparedStatement ps, int i)
					throws SQLException {
				ps.setBoolean(1, true);
				ps.setLong(2, users.get(i).getId());
			}
			
		});
		
	}

	@Override
	public void batchDelete(final String[] ids) {
		final String sql="delete from rams_user where id=?";
		final String delUserRoleSql="delete from rams_user_r_role where USER_ID=?";
		final String delUserCateSql="delete from rams_user_r_category where USER_ID=? ";
		final String delUserFavSql="delete from rams_user_favorite where USER_ID=? ";
		BatchPreparedStatementSetter bss=new BatchPreparedStatementSetter(){

			@Override
			public int getBatchSize() {
				return ids.length;
			}

			@Override
			public void setValues(PreparedStatement ps, int i)
					throws SQLException {
					ps.setLong(1, Long.parseLong(ids[i]));
			}
			
		};
		jdbcTemplate.batchUpdate(delUserRoleSql, bss);
		jdbcTemplate.batchUpdate(delUserCateSql, bss);
		jdbcTemplate.batchUpdate(delUserFavSql, bss);
		jdbcTemplate.batchUpdate(sql, bss);
		
	}

	@Override
	public void addRole(Long id, Long emp) {
		final String sql="insert into rams_user_r_role values("+id+","+emp+")";
		jdbcTemplate.execute(sql);
	}

	@Override
	public List<String> findAllUsername() {
		final String sql="select username from User where isLocal=false and locked=false and deptment<>?";
		return getHibernateTemplate().find(sql,new Object[]{"党委/工会"});
	}
	
	
	
}
